using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using CreamX.Framework.Game.Components;
using CreamX.Common;

namespace CreamX.Framework.Game
{
    public class CircleCollisionBody : SceneCollisionBody
    {

        public BoundingSphere BoundingSphere
        {
            get { return _sceneObject.GetBoundingSphere(); }
        }

        public CircleCollisionBody(CreamXObject sceneobject)
        {
            _sceneObject = sceneobject;
        }
        CreamXCollisionData _colData;
        internal override void TestMove(float time, Vector2 velocity, List<CreamXCollisionData> collisions, CreamXObject hit)
        {
            CreamXCollisionComponent col = hit.GetComponent<CreamXCollisionComponent>();
            bool _hit = false;
            if (!hit.CheckType(_sceneObject.Collision.IgnoreTypes))
            {
                switch (col.CollisionType)
                {
                    case CollisionType.Circle:
                        Vector2 loc = VectorUtil.PointToLocalSpace(hit.Position, velocity, new Vector2(-velocity.Y, velocity.X), _sceneObject.Position);
                        _hit = this.BoundingSphere.Intersects(hit.GetBoundingSphere()) && loc.X > 0;
                        break;
                    case CollisionType.Square:
                        _hit = this.BoundingSphere.Intersects(hit.GetBoundingBox());
                        break;
                    case CollisionType.Tile:
                        //_hit = this.BoundingSphere.Intersects(hit.GetBoundingBox());
                        ((TileCollisionBody)col.CollisionBody).TestMove(time, velocity, collisions, _sceneObject);
                        break;
                }
            }
            if (_hit)
            {
                _colData.SceneObject = hit;
                _colData.Normal = Vector2.Zero;
                collisions.Add(_colData);
            }
        }
    }


    public class TileCollisionBody : SceneCollisionBody
    {
        public int TileLayer = 0;
        public BoundingBox BoundingBox
        {
            get { return _sceneObject.GetBoundingBox(); }
        }
        CreamXTileGrid TileGrid;
        public TileCollisionBody(CreamXObject sceneobject)
        {
            _sceneObject = sceneobject;
            TileGrid = (CreamXTileGrid)sceneobject;
        }
        CreamXCollisionData co = new CreamXCollisionData();
        internal override void TestMove(float time, Vector2 velocity, List<CreamXCollisionData> collisions, CreamXObject hit)
        {
            bool _hit = false;
            TileLayer layer = TileGrid._comp.TileLayers[TileLayer];
            foreach (Tile tile in layer.Tiles)
            {
                if (tile.TileNumber == -1)
                    continue;
                Vector3 tl = new Vector3(
                    tile.Position.X,
                    tile.Position.Y, 0);
                BoundingBox re = new BoundingBox(tl,tl+ new Vector3(
                    TileGrid._comp.TileDisplaySizeX,
                    TileGrid._comp.TileDisplaySizeY, 0));
                
                CreamXCollisionComponent col = hit.GetComponent<CreamXCollisionComponent>();
                
                switch (col.CollisionType)
                {
                    case CollisionType.Circle:
                        _hit = re.Intersects(hit.GetBoundingSphere());
                        break;
                    case CollisionType.Square:
                        _hit = re.Intersects(hit.GetBoundingBox());
                        break;
                }
                if (_hit)
                {
                    CollisionBounds = re;
                    break;
                }

            }


            if (_hit)
            {
                co.SceneObject = _sceneObject;
                collisions.Add(co);
            }
            WasHit = _hit;
        }
        public bool WasHit = false;
        public BoundingBox CollisionBounds;
    }
}
